---@class RedRob.PoolMgr
local PoolMgr = RedRob.CreateSingleton("PoolMgr")
local this = PoolMgr
function PoolMgr.OnCreate()
    this.cacheDataList = {}
    ---@type table<number,RedRob.StateBase[]>
    this.cacheStateList = {}        --状态缓存
    ---@type table<number,RedRob.AiBase[]>
    this.cacheAiList = {}       --ai缓存
    ---@type table<string,GameObject[]>
    this.resObjList = {}        --资源缓存
    this.resObjRequestList = {} --资源加载回调
    ---@type table<number,RedRob.EffectBase[]>
    this.cacheEffectList = {} --特效缓存
    ---@type RedRob.Buffer[]
    this.cacheBufferList = {}   --buff缓存
    this.staticId = 0
end
function PoolMgr.OnDestroy()
    this.cacheDataList = nil
    this.cacheStateList = nil
    this.cacheAiList = nil
    this.resObjList = nil
    if this.resObjRequestList then
        for k,v in pairs(this.resObjRequestList) do
            TablePool.ReleaseDeeper(v,false)
        end
    end
    this.resObjRequestList = nil
end
--region state
function PoolMgr.GetStateFromPool(stateId)
    local list = this.cacheStateList[stateId]
    if list and #list > 0 then
        return table.remove(list)
    end
    local state = RedRob.Config.ActionStateMapping[stateId]
    if not state then
        logError("未注册该状态 "..stateId)
        return nil
    end
    return state.New(stateId)
end
---@param state RedRob.StateBase
function PoolMgr.ReturnStateToPool(state)
    local tb = this.cacheStateList[state.stateId] or {}
    table.insert(tb,state)
    this.cacheStateList[state.stateId] = tb
end
--endregion state
--region stateData
function PoolMgr.GetStateDataFromPool()
    local tb
    if #this.cacheDataList > 0 then
        tb = table.remove(this.cacheDataList)
    else
        tb = {}
    end
    return tb
end
function PoolMgr.ReturnStateDataToPool(tb)
    if tb == nil then return end
    if type(tb) == "table" then
        table.clear(tb)
        table.insert(this.cacheDataList,tb)
    end
end
--endregion stateData
--region AiBase
function PoolMgr.GetAiFromPool(aiType)
    local list = this.cacheAiList[aiType]
    if list and #list > 0 then
        return table.remove(list)
    end
    local ai = RedRob.Config.AiMapping[aiType]
    if not ai then
        logError("未注册该ai "..aiType)
        return nil
    end
    return ai.New(aiType)
end
---@param ai RedRob.AiBase
function PoolMgr.ReturnAiToPool(ai)
    if ai == nil then return end
    local _list = this.cacheAiList[ai.aiType]
    if not _list then
        _list = {}
        this.cacheAiList[ai.aiType] = _list
    end
    table.insert(_list,ai)
end
--endregion AiBase
--region resObj
---@private
function PoolMgr.GetUniqueId()
    this.staticId = this.staticId + 1
    return this.staticId
end
function PoolMgr.LoadPrefabFromPool(path,callback,tb,param)
    local _list = this.resObjList[path]
    if _list and #_list > 0 then
        local obj = table.remove(_list)
        obj:SetActive(true)
        if callback then
            callback(tb,obj,param)
        end
        return 0
    end
    local id = this.LoadPrefab(path,callback,tb,param)
    return id
end
---@param obj GameObject
function PoolMgr.ReturnPrefabToPool(path,obj)
    if path == "" or not obj then return end
    RedRob.SceneMgr.AddPoolChild(obj.transform)
    obj:SetActive(false)
    local _list = this.resObjList[path]
    if not _list then
        _list = {}
        this.resObjList[path] = _list
    end
    table.insert(_list,obj)
end
---@private
function PoolMgr.LoadCallback(path,obj)
    local _list = TablePool.Get()
    for k,v in pairs(this.resObjRequestList) do
        _list[k] = v
    end
    for k,data in pairs(_list) do
        if data.path == path then
            obj = newObject(obj)
            data.callback(data.tb,obj,data.param)
            TablePool.ReleaseDeeper(data,false)
            this.resObjRequestList[k] = nil
        end
    end
    TablePool.ReleaseDeeper(_list,false)
end
---@private
function PoolMgr.LoadPrefab(path,callback,tb,param)
    local id = this.GetUniqueId()
    local _table = TablePool.Get()
    _table.callback = callback
    _table.tb = tb
    _table.param = param
    _table.path = path
    this.resObjRequestList[id] = _table
    resMgr:LoadModelPrefab(path,function(obj1)
        this.LoadCallback(path,obj1)
    end)
    return id
end
function PoolMgr.CancelLoad(requestId)
    if requestId == nil then return end
    TablePool.ReleaseDeeper(this.resObjRequestList[requestId],false)
    this.resObjRequestList[requestId] = nil
end

--endregion resObj
--region effectBase
---@return RedRob.EffectBase
function PoolMgr.GetEffectFromPool(id,_type)
    local _list = this.cacheEffectList[_type]
    if _list and #_list > 0 then
        local eff = table.remove(_list)
        eff.id = id
        return eff
    end
    local eff = RedRob.Config.EffectMapping[_type]
    if not eff then
        logError("未注册该Effect ".._type)
        return nil
    end
    return eff.New(id,_type)
end
---@param effect RedRob.EffectBase
function PoolMgr.ReturnEffectToPool(effect)
    if effect == nil then return end
    local _list = this.cacheEffectList[effect.effectType]
    if not _list then
        _list = {}
        this.cacheEffectList[effect.effectType] = _list
    end
    for k,v in pairs(_list) do
        if v == effect then
            return
        end
    end
    table.insert(_list,effect)
end
--endregion effectBase
--region Buffer
---@return RedRob.Buffer
function PoolMgr.GetBufferFromPool()
    local _list = this.cacheBufferList
    if _list and #_list > 0 then
        local b = table.remove(_list)
        return b
    end
    return RedRob.Buffer.New()
end
---@param buffer RedRob.Buffer
function PoolMgr.ReturnBufferToPool(buffer)
    if buffer == nil then return end
    table.insert(this.cacheBufferList,buffer)
end
--endregion Buffer